﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Se.Framework.Web.Mvc.GenericCrud.Attributes
{
    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
    public class GenericCrudTableDataAttribute : Attribute, IGenericCrudTableData
    {
        public GenericCrudTableDataAttribute(string name, Type entityType, string keyFieldNames)
        {
            this.Name = name;
            this.EntityType = entityType;
            this.KeyFieldName = keyFieldNames;
            CanEdit = true;
            CanDelete = true;
            CanInsert = true;
            CanSearch = true;
        }

        public string Name { get; private set; }

        public bool CanEdit { get; set; }

        public bool CanDelete { get; set; }

        public bool CanInsert { get; set; }

        public bool CanSearch { get; set; }

        public Type EntityType { get; private set; }

        public Type MetadataType { get; set; }

        public string KeyFieldName
        {
            get;
            private set;
        }

        public IDictionary<string, IGenericCrudColumnData> Columns
        {
            get
            {
                return columns ?? (columns = GetPropertiesMetadata());
            }
        }

        private IDictionary<string, IGenericCrudColumnData> columns;

        private IDictionary<string, IGenericCrudColumnData> GetPropertiesMetadata()
        {
            if (this.columns == null)
            {
                var comparer = new PropertiesOrderComparer();
                this.columns = (MetadataType ?? EntityType).GetProperties()
                                                              .Select(x => GenericCrudColumnData.BuildFromMetadata(x))
                                                              .Cast<IGenericCrudColumnData>()
                                                              .OrderBy(x => x.DisplayAttr, comparer)
                                                              .ToDictionary<IGenericCrudColumnData, string>(p => p.Name);
            }
            return columns;
        }
    }
}